package controllers

import (
	"classmates/models"
	"encoding/json"
	"errors"
	"strconv"
	"strings"
	"time"

	beego "github.com/beego/beego/v2/server/web"
)

// ClassmatesController operations for Classmates
type ClassmatesController struct {
	beego.Controller
}

func (c *ClassmatesController) Index() {
	c.TplName = "index.html"
}

// Post ...
// @Title Post
// @Description create Classmates
// @Param	body		body 	models.Classmates	true		"body for Classmates content"
// @Success 201 {int} models.Classmates
// @Failure 403 body is empty
// @router / [post]
func (c *ClassmatesController) Post() {
	var v models.Classmates
	if err := json.Unmarshal(c.Ctx.Input.RequestBody, &v); err == nil {
		v.Createtime = time.Now()

		if _, err := models.AddClassmates(&v); err == nil {
			c.Data["json"] = v
		} else {
			c.Data["json"] = err.Error()
		}
	} else {
		c.Data["json"] = err.Error()
	}
	c.ServeJSON()
}

// signIn ...
// @Title 签到
// @Description 考勤签到
// @Param	body		body 	models.Records	true		"body for Records content"
// @Success 200 {object} models.Records
// @Failure 403 :id is empty
// @router /signIn/ [post]
func (c *ClassmatesController) SignIn() {
	var v models.Records
	result := make(map[string]interface{})
	if err := json.Unmarshal(c.Ctx.Input.RequestBody, &v); err == nil {
		v.Createtime = time.Now()
		v.Now = time.Now()
		target := models.AllClassMates[v.Sn]

		if target == nil || (target.Name != v.Name) {

			result["code"] = 0
			result["data"] = v.Name + "学号不对"
			c.Data["json"] = result
			c.ServeJSON()
			return
		}

		if _, err := models.AddRecords(&v); err == nil {
			query := make(map[string]string)
			query["sn"] = v.Sn
			records, err := models.GetStudentRecords(query, 0, 1000)
			if err != nil {
				result["code"] = 0
				result["data"] = err.Error()
				c.Data["json"] = result
				c.ServeJSON()
				return
			}
			result["code"] = 1
			result["user"] = models.AllClassMates[v.Sn]
			result["data"] = records
			c.Data["json"] = result
			c.ServeJSON()
			return
		} else {

			if strings.Contains(err.Error(), "Duplicate") {

				result["code"] = 0
				result["data"] = "今天重复提交"
				c.Data["json"] = result
				c.ServeJSON()
				return
			} else {
				result["code"] = 0
				result["data"] = err.Error()
				c.Data["json"] = result
				c.ServeJSON()
				return
			}

		}
	} else {
		result["code"] = 0
		result["data"] = err.Error()
		c.Data["json"] = result
	}
	c.ServeJSON()
}

// GetAll ...
// @Title Get All
// @Description get Classmates
// @Param	query	query	string	false	"Filter. e.g. col1:v1,col2:v2 ..."
// @Param	fields	query	string	false	"Fields returned. e.g. col1,col2 ..."
// @Param	sortby	query	string	false	"Sorted-by fields. e.g. col1,col2 ..."
// @Param	order	query	string	false	"Order corresponding to each sortby field, if single value, apply to all sortby fields. e.g. desc,asc ..."
// @Param	limit	query	string	false	"Limit the size of result set. Must be an integer"
// @Param	offset	query	string	false	"Start position of result set. Must be an integer"
// @Success 200 {object} models.Classmates
// @Failure 403
// @router / [get]
func (c *ClassmatesController) GetAll() {
	var fields []string
	var sortby []string
	var order []string
	var query = make(map[string]string)
	var limit int64 = 10
	var offset int64

	// fields: col1,col2,entity.col3
	if v := c.GetString("fields"); v != "" {
		fields = strings.Split(v, ",")
	}
	// limit: 10 (default is 10)
	if v, err := c.GetInt64("limit"); err == nil {
		limit = v
	}
	// offset: 0 (default is 0)
	if v, err := c.GetInt64("offset"); err == nil {
		offset = v
	}
	// sortby: col1,col2
	if v := c.GetString("sortby"); v != "" {
		sortby = strings.Split(v, ",")
	}
	// order: desc,asc
	if v := c.GetString("order"); v != "" {
		order = strings.Split(v, ",")
	}
	// query: k:v,k:v
	if v := c.GetString("query"); v != "" {
		for _, cond := range strings.Split(v, ",") {
			kv := strings.SplitN(cond, ":", 2)
			if len(kv) != 2 {
				c.Data["json"] = errors.New("Error: invalid query key/value pair")
				c.ServeJSON()
				return
			}
			k, v := kv[0], kv[1]
			query[k] = v
		}
	}

	l, err := models.GetAllClassmates(query, fields, sortby, order, offset, limit)
	if err != nil {
		c.Data["json"] = err.Error()
	} else {
		c.Data["json"] = l
	}
	c.ServeJSON()
}

// Put ...
// @Title Put
// @Description update the Classmates
// @Param	id		path 	string	true		"The id you want to update"
// @Param	body		body 	models.Classmates	true		"body for Classmates content"
// @Success 200 {object} models.Classmates
// @Failure 403 :id is not int
// @router /:id [put]
func (c *ClassmatesController) Put() {
	idStr := c.Ctx.Input.Param(":id")
	id, _ := strconv.Atoi(idStr)
	v := models.Classmates{Id: id}
	if err := json.Unmarshal(c.Ctx.Input.RequestBody, &v); err == nil {
		if err := models.UpdateClassmatesById(&v); err == nil {
			c.Data["json"] = "OK"
		} else {
			c.Data["json"] = err.Error()
		}
	} else {
		c.Data["json"] = err.Error()
	}
	c.ServeJSON()
}
